<?php
namespace app\controller;

use app\BaseController;
use think\facade\Db;
use think\Request;
use think\facade\View;
use think\helper\Str;
use app\validate\CheckMembers;
use think\exception\ValidateException;
use EasyWeChat\Factory;
use think\facade\Queue;

// 员工管理
class Members extends BaseController
{
    // 获取部门
    public function getDepartment()
    {

        $result = Db::name('branch')
            ->field('id, title, pid as parentId')
            ->order('sort asc,id asc')
            ->select()->toArray();

        $branch = getTree2($result, 'id', 'parentId');
        header('Content-Type:application/json; charset=utf-8');
        $data = [
            'status' => [
                'code' => 200,
                'message' => 'ok'
            ],
            'data' => $branch
        ];
        return json($data);
    }


    public function index()
    {
        $timing = Db::name('timing')->where('name', '=', '课程规则更新')->where('state', '=', 1)->find();
        if ($timing) {
            $info = '规则更新执行中...';
        } else {
            $info = '规则更新已完成...';
        }
        View::assign('info', $info);
        return View::fetch();
    }



    //+员工数据加载
    public function load(Request $request)
    {

        if(!check_jurisdiction(session('admin_auth.role_id'), $this->control, $this->action)) {
            return json(['code' => 500, 'data' => '', 'msg' => '无操作权限']);
        }

        $get = $request->get();

        if (isset($get['field']) && isset($get['order'])) {
            if (!empty($get['field']) && !empty($get['order'])) {
                $field = $get['field'];
                $sort = $get['order'];
                $where = session('members_where');
            } else {
                $field = 'id';
                $sort = 'asc';
                $where = session('members_where');
            }
        } else {
            $field = 'id';
            $sort = 'asc';
            $where = [];

            if (isset($get['tree_select_nodeId'])) {
                if (!empty($get['tree_select_nodeId'])) {
                    $department = $get['tree_select_nodeId'];
                    $arr = get_children($department, 1);
                    $arr[] = $department;
                    $department = implode('|', $arr);
                    $where[]  = ['', 'EXP', Db::raw("CONCAT(',',a.department,',') REGEXP concat(',(',replace('".$department."',',','|'),'),')")];
                }
            }

            if (isset($get['min']) && isset($get['max'])) {
                if ($get['min'] != '' && $get['max'] != '') {
                    $where[] = ['a.xiashu', 'between', [$get['min'], $get['max']]];
                }
            }

            if (isset($get['role'])) {
                if (!empty($get['role'])) {
                    $where[] = ['a.role', '=', $get['role']];
                }
            }

            if (isset($get['is_manager'])) {
                if ($get['is_manager'] != '') {
                    $where[] = ['a.is_manager', '=', $get['is_manager']];
                }
            }

            if (isset($get['time'])) {
                if (!empty($get['time'])) {
                    $t = explode(' - ', $get['time']);
                    $where[] = ['a.in_time', 'between', [strtotime($t[0]), strtotime($t[1])+86399]];
                }
            }

            if (isset($get['time1'])) {
                if (!empty($get['time1'])) {
                    $t = explode(' - ', $get['time1']);
                    $where[] = ['a.last_time', 'between', [strtotime($t[0]), strtotime($t[1])+86399]];
                }
            }

            if (isset($get['key'])) {
                if (!empty($get['key'])) {
                    $where[] = ['a.name|a.userid', 'like', '%'.$get['key'].'%'];
                }
            }

            $where[] = ['a.status', '<>', 3];
            session('members_where', $where);
        }


        $total = Db::table('o_members')
            ->alias('a')
            ->where($where)
            ->count();


        $rows = Db::table('o_members')
            ->alias('a')
            ->join('o_integral c', 'c.userid=a.userid', 'left')
            ->where($where)
            ->field('a.*, c.num as integral')
            ->order("$field", "$sort")
            ->page($get['page'], $get['limit'])
            ->select()->toArray();

        foreach ($rows as &$v) {
            $count = mb_strlen($v['userid']);
            if ($count == 6) {
                if (is_numeric($v['userid'])) {
                    $v['userid'] = '00'.$v['userid'];
                }
            }

            if ($v['in_time'] != '') {
                $v['in_time'] = date('Y-m-d H:i',$v['in_time']);
            } else {
                $v['in_time'] = '-------';
            }

            if ($v['last_time'] != 0) {
                $v['last_time'] = date('Y-m-d H:i',$v['last_time']);
            } else {
                $v['last_time'] = '-------';
            }
        }
        $data = array(
            'code'=> 0,
            'msg'=> '',
            'count' => $total,
            'data'=> $rows
        );
        return json($data);
    }


    // 数据导出
    public function export()
    {
        if(!check_jurisdiction(session('admin_auth.role_id'), $this->control, $this->action)) {
            return $this->outputAjax('无操作权限');
        }
        ob_end_clean ();
        set_time_limit(0);
        //设置程序运行内存
        ini_set('memory_limit', '4096M');

        $fileName = '员工数据'.date('Ymd', time());
        header('Content-Encoding: UTF-8');
        header("Content-type:application/vnd.ms-excel;charset=UTF-8");
        header('Content-Disposition: attachment;filename="' . $fileName . '.csv"');


        //打开php标准输出流
        $fp = fopen('php://output', 'a');

        //添加BOM头，以UTF8编码导出CSV文件，如果文件头未添加BOM头，打开会出现乱码。
        fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));


        //添加导出标题
        fputcsv($fp, ['工号', '姓名', 'Division', '部门', '职位', '职务', '发帖数', '点赞数', '评论数', '回复数', '总积分', '粉丝数', '关注数', '最近登录时间']);

        //链接数据库
        $where = session('members_where');

        // 发帖数
        $subQuery = Db::table('o_topic')
            ->field('uid, count(id) as topic_num')
            ->group('uid')
            ->buildSql();

        // 点赞数
        $subQuery1 = Db::table('o_zan')
            ->field('uid, count(id) as zan_num')
            ->group('uid')
            ->buildSql();

        // 评论数
        $subQuery2 = Db::table('o_comment')
            ->where('pid', '=', 0)
            ->field('uid, count(id) as comment_num')
            ->group('uid')
            ->buildSql();

        // 回复数
        $subQuery3 = Db::table('o_comment')
            ->where('pid', '>', 0)
            ->field('uid, count(id) as huifu_num')
            ->group('uid')
            ->buildSql();

        // 粉丝数
        $subQuery4 = Db::table('o_follow')
            ->field('aid, count(id) as fensi_num')
            ->group('aid')
            ->buildSql();

        // 关注数
        $subQuery5 = Db::table('o_follow')
            ->field('uid, count(id) as guanzhu_num')
            ->group('uid')
            ->buildSql();

        $total = Db::table('o_members')
            ->alias('a')
            ->alias('a')
            ->join('o_integral c', 'c.userid=a.userid', 'left')
            ->join($subQuery.'d','a.id=d.uid','left')
            ->join($subQuery1.'e','a.id=e.uid','left')
            ->join($subQuery2.'f','a.id=f.uid','left')
            ->join($subQuery3.'g','a.id=g.uid','left')
            ->join($subQuery4.'i','a.id=i.aid','left')
            ->join($subQuery5.'j','a.id=j.uid','left')
            ->where($where)
            ->count();

        $nums = 1000; //每次导出数量
        $step = ceil($total/$nums); //循环次数

        for($i = 0; $i < $step; $i++) {
            $start = $i * $nums;
            $rows = Db::table('o_members')
                ->alias('a')
                ->join('o_integral c', 'c.userid=a.userid', 'left')
                ->join($subQuery.'d','a.id=d.uid','left')
                ->join($subQuery1.'e','a.id=e.uid','left')
                ->join($subQuery2.'f','a.id=f.uid','left')
                ->join($subQuery3.'g','a.id=g.uid','left')
                ->join($subQuery4.'i','a.id=i.aid','left')
                ->join($subQuery5.'j','a.id=j.uid','left')
                ->where($where)
                ->field('a.*, c.num as integral, d.topic_num, e.zan_num, f.comment_num, g.huifu_num, i.fensi_num, j.guanzhu_num')
                ->limit($start, $nums)
                ->group('a.id')
                ->select()
                ->toArray();
            $role = [1 => '员工', 2 => 'HR', 3 => '老师'];
            foreach ($rows as $value) {
                $count = mb_strlen($value['userid']);
                if ($count == 6) {
                    if (is_numeric($value['userid'])) {
                        $userid = "'00".$value['userid'];
                    } else {
                        $userid = $value['userid'];
                    }
                } else {
                    $userid = $value['userid'];
                }


                $arr = [
                    $userid,
                    $value['name'],
                    $value['division'],
                    $value['department_name'],
                    $value['position'],
                    isset($role[$value['role']]) ? $role[$value['role']] : '',
                    $value['topic_num'],
                    $value['zan_num'],
                    $value['comment_num'],
                    $value['huifu_num'],
                    $value['integral'],
                    $value['fensi_num'],
                    $value['guanzhu_num'],
                    $value['last_time'] ? date('Y-m-d', $value['last_time']) : ''
                ];
                fputcsv($fp, $arr);
            }
            //每1千条数据就刷新缓冲区
            flush();
        }
    }



    /*
     * 修改
     */
    public function edit(Request $request)
    {
        $id = $request->param('id');

        $inf = Db::table('o_members')
            ->alias('a')
            ->join('o_integral b', 'b.userid=a.userid', 'left')
            ->where('a.id', '=', $id)
            ->field('a.*, b.num as integral')
            ->find();

        if ($inf['in_time']) {
            $inf['in_time'] = date('Y-m-d', $inf['in_time']);
        }
        $inf['mobile'] = Str::substr(decrypts($inf['mobile']), 0, $length = 11);
        $inf['email'] = decrypts($inf['email']);

        $count = mb_strlen($inf['userid']);
        if ($count == 6) {
            if (is_numeric($inf['userid'])) {
                $inf['userid'] = '00'.$inf['userid'];
            }
        }
        View::assign('inf',$inf);
        return View::fetch();
    }


    public function modify(Request $request)
    {
        if(!check_jurisdiction(session('admin_auth.role_id'), $this->control, $this->action)) {
            return $this->outputAjax('无操作权限');
        }

        $post = $request->post();
        $post = remove_xss($post);

        // 验证
        try {

            validate(CheckMembers::class)->check($post);

        } catch (ValidateException $e) {

            return $this->outputAjax($e->getError());
        }

        try {
            $update = array(
                'id'          => $post['id'],
                'mobile'      => encrypts($post['mobile']),
                'role'        => $post['role'],
                'in_time'     => strtotime($post['in_time']),
                'update_time' => time(),
            );
            if (!Db::name('members')->update($update)) {
                return $this->outputAjax('操作失败！');
            }
            return $this->outputAjax('操作成功！',0);
        } catch (\Exception $e) {
            return $this->outputAjax($e->getMessage());
        }
    }



    // 导入
    public function import()
    {
        return View::fetch();
    }


    // 执行导入
    public function executeImport(Request $request)
    {
        if(!check_jurisdiction(session('admin_auth.role_id'), $this->control, $this->action)) {
            return $this->outputAjax('无操作权限', 2);
        }

        set_time_limit(0);

        $filename = $request->param('path');

        try {

            // 获取excel表格数据
            $result = get_excel_info($filename);

            if ($result['code'] == 1) {
                return $this->outputAjax($result['msg'], 2);
            }

            $i = 0;
            foreach ($result['data'] as $key => $value) {
                $userid = $value[0];
                $time = Db::name('members')->where('userid', '=', $userid)->value('in_time');

                $update = [];

                if (empty($time)) {
                    if (!empty($value['in_time'])) {
                        $update['in_time'] = intval(($value[2] - 25569) * 3600 * 24); //转换成1970年以来的秒数
                    }
                }

                if (isset($value[1])) {
                    $update['name'] = $value[1];
                }

                if (isset($value[3])) {
                    $update['function'] = $value[3];
                }
                if (isset($value[4])) {
                    $update['position'] = $value[4];
                }
                if (isset($value[5])) {
                    $update['division'] = $value[5];
                }
                if (isset($value[6])) {
                    $update['division_mt'] = $value[6];
                }
                if (isset($value[7])) {
                    $update['entity'] = $value[7];
                }
                if (isset($value[8])) {
                    $update['entity_mt'] = $value[8];
                }
                if (isset($value[9])) {
                    $update['activity_sector'] = $value[9];
                }
                if (isset($value[10])) {
                    $update['department_name'] = $value[10];
                }
                if (isset($value[11])) {
                    $update['region'] = $value[11];
                }
                if (isset($value[12])) {
                    $update['office_location'] = $value[12];
                }
                if (isset($value[13])) {
                    $update['services_year'] = floor($value[13]);
                }
                if (isset($value[14])) {
                    $update['age'] = floor($value[14]);
                }
                if (isset($value[15])) {
                    $update['nationality'] = $value[15];
                }
                if (isset($value[16])) {
                    $update['xiashu'] = $value[16];
                }
                $update['is_old'] = 1; //导入默认为老员工


                $f = Db::name('members')->where('userid', '=', $userid)->update($update);
                if ($f) {
                    $i++;
                }
            }


            return $this->outputAjax('导入成功！', 0, [$i, count($result['data'])-$i]);
        } catch (\Exception $e) {
            return $this->outputAjax($e->getMessage(), 2);
        }
    }


    // 员工删除
    public function delete(Request $request)
    {
        if(!check_jurisdiction(session('admin_auth.role_id'), $this->control, $this->action)) {
            return $this->outputAjax('无操作权限');
        }

        $id = $request->post('id');

        try {
            if (!Db::name('members')->where('id', 'in', $id)->update(['status' => 3])) {
                return $this->outputAjax('删除失败！');
            }
            return $this->outputAjax('删除成功！',0);
        } catch (\Exception $e) {
            return $this->outputAjax($e->getMessage());
        }
    }


    //+同步学员
    public function qySaveToLocal()
    {
        if(!check_jurisdiction(session('admin_auth.role_id'), $this->control, $this->action)) {
            return $this->outputAjax('无操作权限');
        }

        set_time_limit(0);
        ini_set('memory_limit','4096M');

        $contacts = Factory::work($this->config);

        // 获取部门列表
        $branch = $contacts->department->list();
        $departments = $branch['department'];

        if ($departments) {

            // 删除旧部门
            Db::name('branch')->where('id', '>', 0)->delete();

            $branch_data = [];

            $branch_id = [];//一级部门

            foreach ($departments as $key => $value) {
                $t = [];
                $t['id'] = $value['id'];
                $t['title'] = $value['name'];
                $t['pid'] = $value['parentid'];
                $t['sort'] = $value['order'];
                $t['add_time'] = time();
                $t['update_time'] = time();

                if ($value['parentid'] == 1) {
                    array_push($branch_id, $value['id']);
                }

                array_push($branch_data, $t);
            }
            // 同步最新部门
            Db::name('branch')->insertAll($branch_data);

            // 旧学员
            $old = Db::name('members')->column('weixin_userid');
            $new = [];

            // 循环查找部门成员
            foreach ($branch_id as &$v_id) {
                $result = $contacts->user->getDetailedDepartmentUsers($v_id, true);
                if ($result['errcode'] == 0) {

                    $result2 = $result['userlist'];

                    $members = array();

                    $members_study = array();

                    $members_integral = array();

                    $membersBfCount = count($result2);

                    for ($i = 0; $i < $membersBfCount; $i++) {

                        if ($result2[$i]['status'] == 1) {
                            $new[] = $result2[$i]['userid'];
                        }
                        //未关注者不进入系统
                        if ($result2[$i]['status'] != 1) {
                            continue;
                        }

                        //已存在
                        if (!in_array($result2[$i]['userid'], $old)) {
                            //未存在
                            $member = $result2[$i];
                            $data = [];
                            $data['cn_name'] = get_user_attr($member, '姓名(中)');
                            $data['name'] = $member['name'];
                            $data['weixin_userid'] = $member['userid'];
                            $data['weixin_status'] = $member['status'];
                            $data['position'] = $member['position'];
                            $data['mobile'] = encrypts($member['mobile']);
                            $data['gender'] = $member['gender'];
                            $data['email'] = encrypts($member['email']);
                            $data['head'] = $member['avatar'] ? $member['avatar'] : 'https://apilearningsparkminiapp.lorealchina.com/static/admin/images/head.png';
                            $data['in_time'] = strtotime(get_user_attr($member, '入职日期'));
                            $data['add_time'] = time();
                            $data['update_time'] = time();
                            $data['update_status'] = 1;
                            $data['status'] = 1;
                            $data['language'] = '';
                            $u = get_user_attr($member, 'carol ID');
                            if ($u != '') {
                                $data['userid'] = (int)get_user_attr($member, 'carol ID');
                            } else {
                                $data['userid'] = ltrim($member['userid'],0);
                            }
                            $departmentArr = $member['department'];
                            $data['department'] = implode(',', $departmentArr);

                            array_push($members, $data);
                            array_push($members_study, ['userid' => $data['userid'], 'update_time' => time()]);
                            array_push($members_integral, ['userid' => $data['userid'], 'update_time' => time()]);
                            array_push($old, $data['weixin_userid']);
                        }
                    }
                    Db::name('members')->insertAll($members);
                    Db::name('members_study')->insertAll($members_study);
                    Db::name('integral')->insertAll($members_integral);
                }
            }

            //寻找差集，标记删除
            if ($new) {
                $del = array_diff($old, $new);
                if ($del) {
                    Db::name('members')->where('weixin_userid', 'in', $del)->update(['status' => 3]);
                }
            }
        } else {
            return $this->outputAjax('当前企业号下没有部门，无法同步！');
        }
        return $this->outputAjax('同步成功！',0,array('new' => count($members), 'del' => count($del)));
    }



    // 更新课程规则
    public function updateCourseRule()
    {
        if(!check_jurisdiction(session('admin_auth.role_id'), $this->control, $this->action)) {
            return $this->outputAjax('无操作权限');
        }

        $res = Db::name('timing')
            ->where('name', '=', '课程规则更新')
            ->where('state', '=', 1)
            ->find();

        if ($res) {
            return $this->outputAjax('课程规则更新中, 请等待执行', 0);
        }


        $ts = time();

        $insert = array(
            'name' => '课程规则更新',
            'state' => 1,
            'add_time' => $ts,
            'date' => date('Ymd', $ts),
        );

        $timing_id = Db::name('timing')->insertGetId($insert);
        if (!$timing_id) {
            return $this->outputAjax('任务添加失败[2]');
        }

        $map1 = [
            ['a.status', '=', 1],
        ];

        $map2 = [
            ['a.start', '>=', time()],
        ];

        $courseid_data = Db::name('flex')
            ->alias('a')
            ->join('o_flex_course b', 'b.flex_id=a.id')
            ->whereOr([ $map1, $map2 ])
            ->column('b.courseid');
        if (empty($courseid_data)) {
            $type = 1; // 没有进行中或即将开始的调研
        } else {
            $type = 2;// 有进行中或即将开始的调研
        }

        // 1.当前任务由哪个类来负责处理
        // 当轮到该任务时，系统将生成该类的实例，并调用其fire方法
        $jobHandlerClassName = 'app\job\UpdateCourseRule';

        // 2.当任务归属的队列名称，如果为新队列，会自动创建
        $jobQueueName = "UpdateCourseRule";

        // 3.当前任务所需业务数据，不能为resource类型，其他类型最终将转化为json形式的字符串
        $jobData = ['ts' => $ts, 'page' => 1, 'timing_id' => $timing_id, 'type' => $type];

        // 4.将该任务推送到消息列表，等待对应的消费者去执行
        // 入队列，later延迟执行，单位秒，push立即执行
        $isPushedTask1 = Queue::push($jobHandlerClassName, $jobData, $jobQueueName);

        // database 驱动时，返回值为 1|false  ;   redis 驱动时，返回值为 随机字符串|false
        if ($isPushedTask1 !== false) {
            return $this->outputAjax('更新课程规则任务添加成功, 请等待执行', 0);

        } else {

            return $this->outputAjax('更新课程规则任务添加失败');

        }
    }
}